#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED显示屏参数
#define SCREEN_WIDTH 128 // OLED显示宽度，以像素为单位
#define SCREEN_HEIGHT 32 // OLED显示高度，以像素为单位

// 声明一个SSD1306显示对象连接到I2C (SDA, SCL引脚)
#define OLED_RESET     -1 // 重置引脚 # (如果共享Arduino重置引脚则为-1)
#define SCREEN_ADDRESS 0x3C // 0.91寸OLED的I2C地址通常是0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);
  
  // SSD1306_SWITCHCAPVCC = 从3.3V生成显示电压
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 failed"));
    for(;;);
  }

  //显示开机启动文字
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Flame V1.0 @Chenxi");
  display.display();
  delay(3000);
}

void loop() {
  // 清除显示缓冲区
  display.clearDisplay();

  // 获取当前时间用于动画
  float time = millis() * 0.01; // 控制动画速度
  
  // 计算火焰跳动偏移
  int flameJumpX = (int)(sin(time * 2.5) * 1); // X轴轻微跳动
  int flameJumpY = (int)(cos(time * 3.2) * 1); // Y轴轻微跳动
  float heightVariation = sin(time * 1.8) * 0.12 + cos(time * 2.1) * 0.08; // 高度变化因子
  int baseX = 20 + flameJumpX;
  int baseY = 16 + flameJumpY;
  
  // 绘制带跳动效果的火焰底部圆形
  display.fillCircle(baseX, baseY, 12, SSD1306_WHITE);

  //绘制烛芯
  // display.fillRect(0, baseY - 1, baseX - 1, 3, SSD1306_BLACK);
  
  //循环绘制动态波浪线（加入跳动效果）
  for(int i = 0; i < 100; i++){
    float angle = i * 0.1 - time; // 添加时间变量让波浪移动
    int wave = sin(angle) * 2; // 控制波浪振幅
    int y = map(i, 0, 100, 0, 15);
    
    // 应用高度变化到火焰线条
    float heightFactor = 1.0 + heightVariation; // 基础高度倍数
    int adjustedY = (int)(y * heightFactor); // 调整后的高度
    
    // 波浪线也跟随火焰底部的跳动
    int lineX = baseX + i;
    int lineY1 = 4 + adjustedY + wave + flameJumpY;
    int lineY2 = 28 - adjustedY + wave + flameJumpY;
    
    // 确保线条不超出屏幕范围
    lineY1 = constrain(lineY1, 0, SCREEN_HEIGHT - 1);
    lineY2 = constrain(lineY2, 0, SCREEN_HEIGHT - 1);
    
    display.drawLine(lineX, lineY1, lineX, lineY2, SSD1306_WHITE);
    if (lineY2 - lineY1 < 1){
      break;
    }
  }
  
  //绘制小火星效果
  for(int i = 0; i < 12; i++) {
    // 使用时间和索引创建伪随机位置，覆盖整个屏幕
    float sparkTime = time + i * 0.3;
    int sparkX = (int)(sin(sparkTime * 0.8 + i) * 60) + (int)(cos(sparkTime * 1.2 + i * 2) * 30) + 64;
    int sparkY = (int)(cos(sparkTime * 0.6 + i * 1.5) * 12) + (int)(sin(sparkTime * 1.5 + i * 3) * 8) + 16;
    
    // 确保火星在屏幕范围内
    if(sparkX >= 0 && sparkX < SCREEN_WIDTH && sparkY >= 0 && sparkY < SCREEN_HEIGHT) {
      // 根据时间控制火星的闪烁效果
      float brightness = (sin(sparkTime * 3 + i * 2) + 1) * 0.5;
      if(brightness > 0.3) { // 只有当亮度足够时才显示火星
        display.drawPixel(sparkX, sparkY, SSD1306_WHITE);
        // 有些火星显示为小十字形，增加视觉效果
        if(i % 3 == 0 && brightness > 0.7) {
          if(sparkX > 0) display.drawPixel(sparkX - 1, sparkY, SSD1306_WHITE);
          if(sparkX < SCREEN_WIDTH - 1) display.drawPixel(sparkX + 1, sparkY, SSD1306_WHITE);
          if(sparkY > 0) display.drawPixel(sparkX, sparkY - 1, SSD1306_WHITE);
          if(sparkY < SCREEN_HEIGHT - 1) display.drawPixel(sparkX, sparkY + 1, SSD1306_WHITE);
        }
      }
    }
  }
  
  // 将缓冲区内容显示到屏幕上
  display.display();
  
  // 延迟一段时间
  delay(20);
}